	/**
 * @author 迷途小羔羊
 * 2014-11-19
 */
	/**MyLoader是一个loader和urlloader封装的多任务加载器*/
	class GYLoader
	{
		/**图片*/public static TYPE_IMAGE = 0;
		/**纹理*/public static TYPE_TEX = 1;
		/**图集(弃用)*/public static TYPE_ATLAS = 2;
		/**swf指定类名的资源(弃用)*/public static TYPE_SWF = 3;
		/**swf资源库(弃用)*/public static TYPE_SWFS = 4;
		/**字体(弃用)*/public static TYPE_FONT = 5;
		/**二进制*/public static TYPE_BINARY = 6;
		/**文本*/public static TYPE_TEXT = 7;
		/**xml(未启用)*/public static TYPE_XML = 8;
		/**json*/public static TYPE_JSON = 9;
		/**variables(弃用)*/public static TYPE_VARIABLES = 10;
		/**swf片段(弃用)*/public static TYPE_MOVIE = 11;
		/**js片段*/public static TYPE_JS = 12;
		/**声音文件*/public static TYPE_SOUND = 13;

		public static _resDict:any={};
		public static _resDataDict:any={};
		private _seqLoaderList:Array<SeqLoader>;
		private _seqURLLoaderList:Array<SeqURLLoader>;
		private _loadList:Array<LoadInfo>;
		private _urlLoadList:Array<LoadInfo>;
		private _loaderReq = new URLRequest();
		private _httpReq = new URLRequest();
		private static _disposed:boolean;
		private static _checkTime;
		private static _checkInterval;
		private static _timeId;
		/**
		 * @param loaderThreads Loader的线程数量 默认为1
		 * @param urlLoaderThreads UrlLoader的线程数量 默认为0
		 * */
		public constructor(loaderThreads=1,urlLoaderThreads=0)
		{
			let s = this;
			
			if(loaderThreads > 0)
			{
				s._seqLoaderList=new Array(loaderThreads);//(loaderThreads,true);
				s._loadList=[];//new Array<LoadInfo>;
			}

			if(urlLoaderThreads > 0)
			{
				s._seqURLLoaderList=new Array(urlLoaderThreads);//(urlLoaderThreads,true);
				s._urlLoadList=[];//new Array<LoadInfo>;
			}
		}
		private getLoader(loadInfo)
		{
			var len;
			var l:SeqLoader,waitL:SeqLoader;
			var s = this;
			len=s._seqLoaderList.length;
			while(--len > -1)
			{
				l=s._seqLoaderList[len];
				if(l)
				{
					if(l.loadInfo)
					{
						if(l.loadInfo.path == loadInfo.path && l.loadInfo.bytes == loadInfo.bytes)
						{
							if(waitL)
								waitL.loadInfo=null;
							waitL=l;
							if(l.isLoading == 2)
							{
								loadInfo.content = l.loadInfo.content;
								loadInfo.callBack();
							}
							else
								l.loadInfo.addLoadInfo(loadInfo, loadInfo.thisObject);
							break;
						}
					}
					else if(waitL==null)
					{
						waitL=l;
						waitL.loadInfo = loadInfo;
					}
				}
				else
				{
					if(waitL == null)
					{
						s._seqLoaderList[len]=waitL=new SeqLoader;
						waitL.on(Laya.Event.COMPLETE,s,s.LoadComp);
						waitL.on(Laya.Event.ERROR,s,s.LoadError);
						//waitL.addEventListener(ProgressEvent.PROGRESS,ProgFunc);
						waitL.loadInfo = loadInfo
					}
					break;
				}
			}
			return waitL;
		}
		private getURLLoader(loadInfo)
		{
			var len;
			var l,waitL;
			var s = this;
			len=s._seqURLLoaderList.length;
			while(--len > -1)
			{
				l=s._seqURLLoaderList[len];
				if(l)
				{
					if(l.loadInfo)
					{
						if(l.loadInfo.path == loadInfo.path)
						{
							if(waitL)
								waitL.loadInfo=null;
							waitL=l;
							if(l.isLoading == 2)
							{
								loadInfo.content = l.loadInfo.content;
								loadInfo.callBack();
							}
							else
								l.loadInfo.addLoadInfo(loadInfo, loadInfo.thisObject);
							break;
						}
					}
					else if(waitL==null)
					{
						waitL=l;
						waitL.loadInfo = loadInfo;
					}
				}
				else
				{
					if(waitL == null)
					{
						s._seqURLLoaderList[len]=waitL=new SeqURLLoader;
						waitL.on(Laya.Event.COMPLETE, s,s.UrlLoadComp);
						waitL.on(Laya.Event.ERROR, s,s.URLLoadError);						
						waitL.on("progress", s,s.UrlProgFunc);
						waitL.loadInfo = loadInfo
					}
					break;
				}
			}
			return waitL;
		}

		/**读取bytes资源 png jpg bmp
		 * @param bytes uint8Array或者ByteArray的buffer属性
		 * @param callBackFunc 回调函数，返回参数为LoadInfo,返回后，loadInfo会自动被清理
		 * @param thisObject callBackFunc的this指向
		 * @param type 加载资源html blob类型 image(如image/png)
		 * @param mimeType blob资源 如"image/png"
		 * @param param 附加参数
		 * */
		public loadBytes(bytes,callBackFunc,thisObject,type = 1,mimeType="image/png",param:any = null)
		{
			var s = this;
			var loadInfo=LoadInfo.getInstance();
			loadInfo.thisObject = thisObject;
			loadInfo.bytes=bytes;
			loadInfo.callBackFunc=callBackFunc;
			// loadInfo.progFunc=progFunc;
			loadInfo.type = type;
			loadInfo.mimeType = mimeType;
			loadInfo.param = param;
			if(GYLoader._resDict[bytes])
			{
				loadInfo.content=GYLoader._resDict[bytes];
				loadInfo.msg="加载完成！";
				callBackFunc(loadInfo);
				loadInfo.clear();
				return;
			}
			var len;
			len=s._loadList.length;
			while(--len>-1)
			{
				if(bytes == s._loadList[len].bytes)
				{
					s._loadList[len].addLoadInfo(loadInfo, loadInfo.thisObject);
					return;
				}
			}
			var l=s.getLoader(loadInfo);
			if(l)
			{
				if(l.isLoading==0)
				{
					l.isLoading = 1;
					l.loadBytes(bytes);					
				}
			}
			else
				s._loadList.push(loadInfo);
			return loadInfo;
		}
		/**读取GYPackager打包的资源
		 * @param bytes uint8Array或者ByteArray的buffer属性
		 * @param callBackFunc 回调函数，返回参数为CompressLoadInfo
		 * @param callBackFunc指向
		 * @param progFunc 回调函数，返回参数为CompressLoadInfo
		 * */
		public loadGYCompressBytes(bytes,callBackFunc,thisObject,version = null,progFunc=null)
		{let s = this;
			var i,len;
			var path:string,cp;
			var type;
			var newBytes:ByteArray;
			var bLen:number;
			var cpLoadInfo:CompressLoadInfo;
			var res;
			bytes = new ByteArray(bytes);
			if(bytes.readUTF() == "GYCompress")
			{
				cpLoadInfo = new CompressLoadInfo;
				cpLoadInfo.callBackFunc = callBackFunc;
				cpLoadInfo.progFunc = progFunc;
				cpLoadInfo.thisObject = thisObject;
				version = version == null?"":"?"+version;
				len = bytes.readUnsignedInt();
				cpLoadInfo.setResCount(len,len);
				for(i=0;i<len;++i)
				{
					path = bytes.readUTF() + version;
					type = bytes.readUnsignedInt();
					cp = bytes.readUTF();
					bLen = bytes.readUnsignedInt();
					newBytes = new ByteArray;
					bytes.readBytes(newBytes,0,bLen);
					newBytes.uncompress(cp);
					if(type == GYLoader.TYPE_IMAGE || type == GYLoader.TYPE_TEX || type == GYLoader.TYPE_SOUND)
						s.loadBytes(newBytes.buffer,cpLoadInfo.callBack,cpLoadInfo,type,GYLoader.getMimeType(type)).path = path;
					else if(type == GYLoader.TYPE_JSON)
					{
						res = ResObject.getInstance();
						res.res = JSON.parse(newBytes.readUTFBytes(newBytes.length));
						res.pathKey = path;
						GYLoader.setDataRes(path,res);
						cpLoadInfo.callBack();
					}
					else if(type == GYLoader.TYPE_TEXT || type == GYLoader.TYPE_JS)
					{
						res = ResObject.getInstance();
						res.res = newBytes.readUTFBytes(newBytes.length);
						res.pathKey = path;
						GYLoader.setDataRes(path,res);
						cpLoadInfo.callBack();
					}
					else
					{
						res = ResObject.getInstance();
						res.res = newBytes.buffer;
						res.pathKey = path;
						GYLoader.setDataRes(path,res);
						cpLoadInfo.callBack();
					}
				}
			}
		}

		/**读取网络资源 swf png jpg bmp
		 * @param path 读取路径
		 * @param callBackFunc 回调函数，返回参数为LoadInfo,返回后，loadInfo会自动被清理
		 * @param thisObject callBackFunc的this指向
		 * @param type 加载资源类型 image(png,jpg), swf, font
		 * */
		public loadPath(path,callBackFunc,thisObject,type=0,param = null)
		{
			var s = this;
			var loadInfo=LoadInfo.getInstance();
			loadInfo.thisObject = thisObject;
			loadInfo.path=path;
			loadInfo.callBackFunc=callBackFunc;
			loadInfo.param = param;
			// loadInfo.progFunc=progFunc;
			loadInfo.type = type;
			loadInfo.sendType = LoadInfo.SEND_RES;
			if(GYLoader._resDict[path])
			{
				loadInfo.content=GYLoader._resDict[path];
				loadInfo.msg="加载完成！";
				callBackFunc.call(loadInfo.thisObject, loadInfo);
				loadInfo.clear();
				return null;
			}
			var len;
			len=s._loadList.length;
			while(--len>-1)
			{
				if(path == s._loadList[len].path)
				{
					s._loadList[len].addLoadInfo(loadInfo, loadInfo.thisObject);
					return loadInfo;
				}
			}
			var l=s.getLoader(loadInfo);
			if(l)
			{
				if(l.isLoading == 0)
				{
					l.isLoading = 1;					
					if(type == GYLoader.TYPE_SOUND)
						l.loadSound(path);
					else
						l.load(path);
				}
			}
			else
				s._loadList.push(loadInfo);
			return loadInfo;
		}
		/**取消加载，当调用loadPath加载资源时，调用此方法取消加载，此方法根据path和callBackFunc寻找此前的加载请求
		 * @param path	加载路径
		 * @param callBackFunc 加载完成的回调
		 * */
		public cancelLoadPath(path, callBackFunc, thisObject)
		{
			var len;
			var l;
			var loadInfo;
			var s = this;
			len=s._seqLoaderList.length;
			while(--len > -1)
			{
				l = s._seqLoaderList[len];
				if(l && l.loadInfo && l.loadInfo.path == path)
				{
					if(l.loadInfo.cancel(callBackFunc, thisObject))
					{
						l.cancelLockTime = Date.now();
						l.callLater(function(seqLoader){
							let sThis = this;
							seqLoader.breakLock();
							sThis.LoadNext(l);
						},s,0);
						l.loadInfo = null;
						s.LoadNext(l);
						return;
					}
				}
			}
			len = s._loadList.length;
			while(--len>-1)
			{
				loadInfo = s._loadList[len];
				if(loadInfo.cancel(callBackFunc, loadInfo.thisObject))
					s._loadList.splice(len,1);
			}
		}
		// private ProgFunc(e:ProgressEvent):void
		// {
		// 	var loadInfo:LoadInfo = e.currentTarget.loader.loadInfo
		// 	loadInfo.prog(e);
		// }
		private LoadError(e)
		{
			var s = this;
			var l = e;//.currentTarget;
			var loadInfo=l.loadInfo;
			if(loadInfo == null)return;
			loadInfo.msg="数据流错误#1";
			l.callLater(s.ErrorNext, s);
		}
		private ErrorNext(l)
		{
			var s = this;
			l.clearCallLater();
			if(l.loadInfo == null)return;
			l.loadInfo.callBack();
			l.loadInfo.clear();
			l.loadInfo=null;
			s.LoadNext(l);
		}
		LoadComp(e)
		{
			var s = this;
			var l;
			var loadInfo;
			var resObj;
			l = e;//.currentTarget;
			loadInfo=l.loadInfo;
			if(loadInfo == null)return;
			l.isLoading = 2;
			resObj = s.getResByLoaderInfo(l);
			if(loadInfo.save)
			{
				if(loadInfo.bytes)
					GYLoader._resDict[loadInfo.bytes] = resObj;
				else
					GYLoader._resDict[loadInfo.path] = resObj;
			}
			loadInfo.content = resObj;
			loadInfo.msg="加载完成";
			loadInfo.callBack();
			loadInfo.clear();
			l.loadInfo=null;
			s.LoadNext(l);
		}
		private getResByLoaderInfo(l)
		{
			var type;
			var resObj;
			var loadInfo;
			loadInfo = l.loadInfo;
			type = loadInfo.type;
			resObj = ResObject.getInstance();
			// if(type == GYLoader.TYPE_IMAGE)
			// 	resObj.res=l.data;//.bitmapData;
			// else 
			if(type == GYLoader.TYPE_IMAGE ||type == GYLoader.TYPE_TEX)
			{				
				resObj.res=new Laya.Texture(l.data);								
			}
			else
				resObj.res=l.data;
			resObj.pathKey = loadInfo.path;
			resObj.type = type;
			return resObj;
		}
		private LoadNext(l)
		{
			var s = this;
			if(s._loadList.length > 0)
			{
				var loadInfo=s._loadList.shift();
				l.loadInfo = loadInfo;
				if(l.isLoading!=1)
				{
					l.isLoading = 1;
					if(loadInfo.bytes)
						l.loadBytes(loadInfo.bytes);
					else
					{
						s._loaderReq.url=loadInfo.path;
						if(loadInfo.type == GYLoader.TYPE_SOUND)
							l.loadSound(loadInfo.path);
						else
							l.load(loadInfo.path);
					}					
				}
				return;
			}
		}
		/**httpSend请求
		 * @param url 请求的url
		 * @param callBackFunc 回调函数，返回参数为LoadInfo
		 * @param thisObject callBackFunc的this指向     *
		 * @param type  二进制(binary)、文本(text)、URL 编码变量(variables) 参考GYLoader常量
		 * @param method 访问方式 get 或者 post
		 * @param header 头部数据(Array[{key,value}])
		 * @param data 发送数据
		 * @param param 回调附加参数object
		 * */
		public httpSend(url:string,callBackFunc:Function, thisObject:any,type:number=7,method:string="get",header:Array<any> = null, data:any = null,contentType:string="",param:any = null)
		{
			var s = this;
			var loadInfo=LoadInfo.getInstance();

			loadInfo.path=url;
			loadInfo.callBackFunc=callBackFunc;			
			loadInfo.thisObject = thisObject;
			loadInfo.type = type;
			loadInfo.method = method;
			loadInfo.param = param;
			loadInfo.contentType = contentType;
			loadInfo.header = header;
			loadInfo.save = false;
			loadInfo.data = data;
			loadInfo.sendType = LoadInfo.SEND_HTTP;
			var len;
			len=s._urlLoadList.length;
			while(--len>-1)
			{
				if(url == s._urlLoadList[len].path)
				{
					s._urlLoadList[len].addLoadInfo(loadInfo,loadInfo.thisObject);
					return loadInfo;
				}
			}
			var l=s.getURLLoader(loadInfo);
			if(l)
			{
				if(l.isLoading == 0)
				{
					s._httpReq.url = loadInfo.path;
					s._httpReq.method = loadInfo.method;
					s._httpReq.dataFormat = loadInfo.dataFormat;
					s._httpReq.data = loadInfo.data;
                	s._httpReq.requestHeaders = loadInfo.header;
					s._httpReq.contentType = contentType;
					l.load(s._httpReq);
					l.isLoading = 1;
				}
			}
			else
				s._urlLoadList.push(loadInfo);
			return loadInfo;
		}
		/**加载数据
		 * @param path 读取路径
		 * @param callBackFunc 回调函数，返回参数为LoadInfo
		 * @param thisObject callBackFunc的this指向
		 * @param progFunc 回调函数，返回参数为ProgressEvent
		 * @param type  二进制(binary)、文本(text)、URL 编码变量(variables)
		 * @param method 访问方式 get 或者 post
		 * */
		public loadData(path,callBackFunc, thisObject,progFunc=null,type=6,method="get",param = null)
		{
			var s = this;
			var loadInfo=LoadInfo.getInstance();

			loadInfo.path=path;
			loadInfo.callBackFunc=callBackFunc;
			loadInfo.progFunc=progFunc;
			loadInfo.thisObject = thisObject;
			loadInfo.type = type;
			loadInfo.method = method;
			loadInfo.param = param;
			loadInfo.sendType = LoadInfo.SEND_DATA;
			if(GYLoader._resDataDict[path])
			{
				loadInfo.content=GYLoader._resDataDict[path];
				loadInfo.msg="加载完成！";
				callBackFunc.call(loadInfo.thisObject,loadInfo);
				loadInfo.clear();
				return null;
			}
			var len;
			len=s._urlLoadList.length;
			while(--len>-1)
			{
				if(path == s._urlLoadList[len].path)
				{
					s._urlLoadList[len].addLoadInfo(loadInfo,loadInfo.thisObject);
					return loadInfo;
				}
			}
			var l=s.getURLLoader(loadInfo);
			if(l)
			{
				if(l.isLoading == 0)
				{
					l.isLoading = 1;
					s._loaderReq.url=path;
					s._loaderReq.method=method;
					s._loaderReq.dataFormat = loadInfo.dataFormat;
					l.load(s._loaderReq);					
				}
			}
			else
				s._urlLoadList.push(loadInfo);
			return loadInfo;
		}
		/**取消加载，当调用loadPath加载数据时，调用此方法取消加载，此方法根据path和callBackFunc寻找此前的加载请求
		 * @param path	加载路径
		 * @param callBackFunc 加载完成的回调
		 * */
		public cancelLoadData(path, callBackFunc, thisObject)
		{
			var s = this;
			var len:number;
			var l:SeqURLLoader;
			var loadInfo:LoadInfo;
			len=s._seqURLLoaderList.length;
			while(--len > -1)
			{
				l = s._seqURLLoaderList[len];
				if(l && l.loadInfo && l.loadInfo.path == path)
				{
					if(l.loadInfo.cancel(callBackFunc,thisObject))
					{
						l.cancelLockTime = Date.now();
						l.callLater(function(l){
							let sThis = this;
							l.breakLock();
							sThis.UrlLoadNext(l)
						},s,0);
						l.loadInfo = null;
						l.close();
					}
					return;
				}
			}
			len = s._urlLoadList.length;
			while(--len>-1)
			{
				loadInfo = s._urlLoadList[len];
				if(loadInfo.cancel(callBackFunc,loadInfo.thisObject))
					s._urlLoadList.splice(len,1);
			}
		}
		private UrlLoadComp(e)
		{
			var s = this;
			var l = e;//.currentTarget;
			var loadInfo;
			var resObj;

			loadInfo =l.loadInfo;
			l.isLoading = 2;
			resObj = s.getResByBytes(l);
			if(loadInfo.save)
			{
				GYLoader._resDataDict[loadInfo.path]=resObj;
			}
			loadInfo.content = resObj;
			loadInfo.msg="加载完成！";
			loadInfo.callBack();
			loadInfo.clear();
			l.loadInfo = null;
			s.UrlLoadNext(l);
		}
		private getResByBytes(l)
		{
			var loadInfo;
			var type;
			loadInfo = l.loadInfo;
			type = loadInfo.type;
			var resObj = ResObject.getInstance();			
			resObj.pathKey = loadInfo.path;
			resObj.type = type;
			if(type == GYLoader.TYPE_SOUND)
			{
				resObj.res = window.URL.createObjectURL(l.data);
			}
			else
				resObj.res = l.data;
			return resObj;
		}
		private URLLoadError(e)
		{
			var s = this;
			var l = e;//.currentTarget;
			var loadInfo=l.loadInfo;
			if(loadInfo == null)return;
			loadInfo.msg="数据流错误！#1";
			loadInfo.callBack();
			l.callLater(s.UrlErrorNext,s);
		}		
		private UrlErrorNext(l)
		{
			var s = this;
			l.clearCallLater();
			if(l.loadInfo == null)return;
			l.loadInfo=null;
			s.UrlLoadNext(l);
		}
		private UrlProgFunc(l:SeqURLLoader)
		{
			var loadInfo = l.loadInfo;			
			loadInfo.prog(l);
		}
		private UrlLoadNext(l)
		{
			var s = this;
			if(s._urlLoadList.length > 0)
			{
				var loadInfo=s._urlLoadList.shift();
				l.loadInfo = loadInfo;
				if(l.isLoading!=1)
				{
					if(loadInfo.sendType == LoadInfo.SEND_HTTP)
					{
						s._httpReq.dataFormat = loadInfo.dataFormat;
						s._httpReq.url = loadInfo.path;
						s._httpReq.method = loadInfo.method;
						s._httpReq.contentType = loadInfo.contentType;
						s._httpReq.requestHeaders = loadInfo.header;
						s._httpReq.data = loadInfo.data;
						l.load(s._httpReq);
					}
					else
					{
						s._loaderReq.dataFormat = loadInfo.dataFormat;
						s._loaderReq.url = loadInfo.path;
						s._loaderReq.method = loadInfo.method;
						s._loaderReq.contentType = loadInfo.contentType;						
						l.load(s._loaderReq);
					}					
					
					l.isLoading = 1;
					return;
				}
			}
		}
		public static getMimeType(type:number, path:string = null):string
		{			
			let arr:Array<string>;
			let ext:string;			
			if(path)
			{
				arr = path.split(".");
				ext = arr.length > 1?arr[arr.length - 1]:null;
				arr = ext.split("?");
				if(arr.length > 1)
				{
					ext = arr[0];
				}
			}
				
			if(type == GYLoader.TYPE_SOUND)
			{				
				if(ext)
					return "audio/" + ext;
				return "audio/basic";
			}
			if(ext == "jpg")
			{
				return "image/jpeg";
			}
			if(ext)
				return "image/" + ext;
			return "image/png";
		}
		/**设置资源回收的时间间隔，为0时不回收*/
		public static setResCheck(val)
		{			
			if(GYLoader._checkInterval > 0)
			{
				clearInterval(GYLoader._timeId);
				// TimeManager.unRegistered(GYLoader._timeId,GYLoader.checkResUse, null);
			}
			GYLoader._checkInterval = val;
			if(val > 0)
			{
				GYLoader._checkTime = Date.now();
				GYLoader._timeId = setInterval(GYLoader.checkResUse, val);
				// GYLoader._timeId = TimeManager.registered(GYLoader.checkResUse);
			}
		}

		public static checkResUse(sysTime)
		{
			if(sysTime - GYLoader._checkTime < GYLoader._checkInterval)
				return;
			GYLoader._checkTime = sysTime;
			var temp=[];
			for (var key in GYLoader._resDict)
			{
				if(GYLoader._resDict[key].count <= 0)
				{
					GYLoader._resDict[key].clear();
					temp.push(GYLoader._resDict[key].pathKey);
				}
			}
			var len;
			len = temp.length;
			while(--len>-1)
				delete GYLoader._resDict[temp[len]];
			temp.length = 0;
			for (var key in GYLoader._resDataDict)
			{
				if(GYLoader._resDict[key].count <= 0)
				{
					GYLoader._resDict[key].clear();
					temp.push(GYLoader._resDict[key].pathKey);
				}
			}
			len = temp.length;
			while(--len>-1)
				delete GYLoader._resDataDict[temp[len]];
			temp.length = 0;
		}
		/**删除包含key键的资源,删除img文件夹下面的资源，如 img/,结尾带上/，以便区分文件夹节点 */
		public static deleteResByKey(deleteKey:string):void
		{			
			var temp=[];
			var ind:number;
			for (var key in GYLoader._resDict)
			{				
				ind = key.indexOf(deleteKey);
				if(ind == 0 || key.indexOf("/" + deleteKey) > -1)
				{
					GYLoader._resDict[key].clear();
					temp.push(GYLoader._resDict[key].pathKey);
				}
			}
			var len;
			len = temp.length;
			while(--len>-1)
				delete GYLoader._resDict[temp[len]];
			temp.length = 0;
			for (var key in GYLoader._resDataDict)
			{
				ind = key.indexOf(deleteKey);
				if(ind == 0 || key.indexOf("/" + deleteKey) > -1)
				{
					GYLoader._resDataDict[key].clear();
					temp.push(GYLoader._resDataDict[key].pathKey);
				}				
			}
			len = temp.length;
			while(--len>-1)
				delete GYLoader._resDataDict[temp[len]];
			temp.length = 0;
		}
		/**获取位图、动画资源*/
		public static getRes(val)
		{
			return GYLoader._resDict[val];
		}
		/**获取二进制数据资源*/
		public static getDataRes(val)
		{
			return GYLoader._resDataDict[val];
		}
		public static setRes(key:string,val:ResObject):void
		{
			GYLoader._resDict[key] = val;
		}
		public static setDataRes(key:string,val:ResObject):void
		{
			GYLoader._resDataDict[key] = val;
		}
		/**销毁加载系统*/
		public static dispose():void
		{
			// GYLoader._disposed = true;
			let resObj:ResObject;
			let dict:any = GYLoader._resDict;
			for (var key in dict) {                              
				resObj = dict[key];
				resObj.clear();
            }
			dict = GYLoader._resDataDict;
			for (var key in dict) {                              
				resObj = dict[key];
				resObj.clear();
            }
			GYLoader._resDict = {};
			GYLoader._resDataDict = {};
		}
	}

	class SeqURLLoader extends Laya.EventDispatcher
	{
		private _loadInfo:LoadInfo;
		private _intervalId:number;
		private _isLoading:number;
		private _xmlHttpRequest:any;
		private _data:any;
		private _cancelLockTime:number;
		public progressData:any;
		private _bindHandleEvent:Function;
		public constructor()
		{
			super();
			let s = this;
			s._loadInfo=null;
			s._intervalId=-1;
			s._isLoading=0;
			s._xmlHttpRequest=null;
			s._data=null;
		}
		public set loadInfo(val)
		{
			var s = this;
			if(val == null)
			{
				s._isLoading=0;
				if(s._cancelLockTime == 0)
					s.clearCallLater();
				if(s._xmlHttpRequest)
					s._xmlHttpRequest.removeEventListener('progress', s._bindHandleEvent);
				s._bindHandleEvent = null;
			}
			s._loadInfo = val;
		}
		public get loadInfo()
		{
			return this._loadInfo;
		}
		public close():void
		{
			let s = this;
			if(s._xmlHttpRequest)s._xmlHttpRequest.abort();
		}
		private handleEvent(e){
			let s = this;
			s.progressData = e;			
			s.event("progress",s);
		}
		public load(req)
		{var s =this;
			let wxData:any;
			let request;
			if (window["wx"])//优先判断微信的request
			{
				s._xmlHttpRequest = window["wx"].request;
				request = s._xmlHttpRequest;
				wxData = {};
				wxData.method = req.method;
				wxData.responseType = req.dataFormat;				
				wxData.dataType = "other";
				wxData.url = req.url;
				wxData.header = {};
			}
			else if (window["XMLHttpRequest"])
			{// code for all new browsers
				s._xmlHttpRequest=new XMLHttpRequest();
				s._bindHandleEvent = s.handleEvent.bind(s);
				s._xmlHttpRequest.addEventListener('progress', s._bindHandleEvent);
			}
			else if (window["ActiveXObject"])
			{// code for IE5 and IE6
				s._xmlHttpRequest=new window["ActiveXObject"]("Microsoft.XMLHTTP");
			}
			request = s._xmlHttpRequest;
			if(request == null)return;
			if(!wxData)//微信sdk的
			{			
				request.open(req.method, req.url, true);
				request.responseType = req.dataFormat;//"arraybuffer";
			}			

			let i,len;
			len = req.requestHeaders.length;
			if(len > 0)
			{
				for(i=0;i<len;++i)
				{
					request.setRequestHeader(req.requestHeaders[i].key,req.requestHeaders[i].value);
				}
			}
			let sendData;
			if (req.method == "get" || !req.data) {
			}
			else if (CommonUtil.GYIs(req.data,URLVariables)) {
				if(wxData)
					wxData.header["Content-Type"] = "application/x-www-form-urlencoded";
				else
					request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				var urlVars = req.data;
				sendData = urlVars.toString();
			}
			else {
				if(req.contentType=="" || req.contentType == null)
				{
					if(wxData)
						wxData.header["Content-Type"] = "multipart/form-data";
					else
						request.setRequestHeader("Content-Type", "multipart/form-data");
				}
				sendData = req.data;
			}

			if(wxData)
			{
				if(req.contentType!="" && req.contentType != null)
				wxData.header["Content-Type"] = req.contentType;
				wxData.success = s.loadComp.bind(s);
				wxData.fail = s.loadError.bind(s);
				wxData.data = sendData;
				s._xmlHttpRequest(wxData);
			}
			else
			{
				if(req.contentType!="" && req.contentType != null)
					request.setRequestHeader("Content-Type",req.contentType);
				request.onreadystatechange = function () {
					if (request.readyState == 4) {
						var ioError = request.status!=200;
						if (ioError) {
							//self.dispatchEventWith(egret.IOErrorEvent.IO_ERROR);
							s.loadError();
						}
						else {
							s.loadComp();
						}
					}
				};
				request.send(req.data);
			}

			
		}
		public get data()
		{
			return this._data;
		}
		private loadComp()
		{
			var s = this;
			s._data = s._xmlHttpRequest.response;
			s.event(Laya.Event.COMPLETE,s);
		}
		private loadError(){
			var s = this;
			s._data = null
			s.event(Laya.Event.ERROR,s);
		}
		/**由于连续加载时，上一个失败立即使用这个loader会产生加载中断的bug，所以进行延时处理*/
		public callLater(func,thisObject,delay=100)
		{
			var s = this;
			s._intervalId = setTimeout(function(sObject,l){
				func.call(sObject, l);
			},delay, thisObject,s);
		}
		/**清理延时*/
		public clearCallLater()
		{
			var s = this;
			if(s._intervalId > -1)
			{
				clearInterval(s._intervalId);
				s._intervalId = -1;
			}
		}
		public get cancelLockTime()
		{
			return this._cancelLockTime;
		}
		public set cancelLockTime(value)
		{
			this._cancelLockTime = value;
		}
		public get isLoading()
		{
			return this._isLoading;
		}
		public set isLoading(val)
		{
			this._isLoading = val;
		}
		public breakLock()
		{var s = this;
			s._cancelLockTime = 0;
		}
	}

	class SeqLoader extends Laya.EventDispatcher
	{
		private _loadInfo:LoadInfo;
		private _intervalId:number;
		private _isLoading:number;
		private _imageLoader:any;
		private _soundLoader:Laya.Sound;
		private _cancelLockTime:number;
		private _data:any;
		public constructor()
		{
			super();
			let s = this;
			s._loadInfo=null;
			s._intervalId=-1;
			s._isLoading=0;
			s._imageLoader=null;
			s._cancelLockTime = 0;
			s._data=null;
		}
		public set loadInfo(val)
		{
			var s = this;
			if(val == null)
			{
				// s.unload();
				s._isLoading=0;
				if(s._cancelLockTime == 0)
					s.clearCallLater();
			}
			s._loadInfo = val;
		}
		public get loadInfo()
		{
			return this._loadInfo;
		}
		public get isLoading()
		{
			return this._isLoading;
		}
		public set isLoading(val)
		{
			this._isLoading = val;
		}
		public loadBytes(bytes)
		{let s = this;
			var blob = new Blob([bytes], {type: s._loadInfo.mimeType});
			var url = URL.createObjectURL(blob);
			if(s._loadInfo.type == GYLoader.TYPE_SOUND)
				s.loadSound(url);
			else
				s.load(url);			
		}
		public loadSound(url:string):void
		{
			let s = this;
			s._soundLoader = new Laya.SoundManager._soundClass;
			s._soundLoader.on(Laya.Event.COMPLETE, s, s.loadSoundComp);
			s._soundLoader.on(Laya.Event.ERROR, s, s.loadSoundError);
			s._soundLoader.load(url);						
		}
		private loadSoundComp():void
		{
			let s= this;
			s._data = s._soundLoader;
			s._soundLoader.off(Laya.Event.COMPLETE, s, s.loadSoundComp);
			s._soundLoader.off(Laya.Event.ERROR, s, s.loadSoundError);
			s.event(Laya.Event.COMPLETE, s);
			var url = s._data.url;
			if (url.indexOf("blob:") == 0) {
				var winURL = window["URL"] || window["webkitURL"];
				try {
					winURL.revokeObjectURL(s._data.src);
				}
				catch (e) {
					console.warn(1037);
				}
			}
		}
		private loadSoundError():void
		{
			let s= this;
			s._data = null;
			s._soundLoader.off(Laya.Event.COMPLETE, s, s.loadSoundComp);
			s._soundLoader.off(Laya.Event.ERROR, s, s.loadSoundError);
			s.event(Laya.Event.ERROR);			
		}
		public load(url)
		{var s =this;
			s._imageLoader = window["wx"]?(<any>window["wx"]).createImage():window.document.createElement("img");
			s._imageLoader.onload = s.loadComp.bind(s);
			s._imageLoader.onerror = s.loadError.bind(s);			
			s._imageLoader.src = url;
			// s._imageLoader = Laya.HTMLImage.create(url,{onload:s.loadComp.bind(s),onerror:s.loadError.bind(s),onCreate:function (img){
			// 			// image=img;
			// 	}})
		}
		get data()
		{
			return this._data;
		}
		private loadComp()
		{
			var s = this;
			//Laya 2.0.1
			// let img:Laya.HTMLImage;			
			// s._imageLoader.onload = null;
			// s._imageLoader.onerror = null;			
			// img = Laya.HTMLImage.create(s._imageLoader.width,s._imageLoader.height,1);
			// img.loadImageSource(s._imageLoader,true);
			//Laya2.1
			// let img:Laya.Texture2D;
			// img = new Laya.Texture2D(s._imageLoader.width, s._imageLoader.height, 1, false, false);
            //             img.wrapModeU = 1;
            //             img.wrapModeV = 1;
            //             img.loadImageSource(s._imageLoader,true);	
			//Laya 1.7
			s._data = Laya.HTMLImage.create(s._imageLoader,s._imageLoader.src);
			s._data["_mipmap"] = false;
			s.event(Laya.Event.COMPLETE,s);
		}
		private loadError(){
			var s = this;
			s._imageLoader.onload = null;
			s._imageLoader.onerror = null;
			s._data = null;
			s.event(Laya.Event.ERROR,s);			
		}
		/**由于连续加载时，上一个失败立即使用这个loader会产生加载中断的bug，所以进行延时处理*/
		public callLater(func,thisObject,delay=100)
		{
			var s = this;
			s._intervalId = setTimeout(function(){
				func.call(thisObject, s);
			},delay, thisObject);
		}
		/**清理延时*/
		public clearCallLater()
		{
			var s = this;
			if(s._intervalId > -1)
			{
				clearInterval(s._intervalId);
				s._intervalId = -1;
			}
		}
		public get cancelLockTime()
		{var s = this;
			return s._cancelLockTime;
		}

		public set cancelLockTime(value)
		{var s = this;
			s._cancelLockTime = value;
		}
		public breakLock()
		{var s = this;
			s._cancelLockTime = 0;
		}
	}	
	class URLRequestHeader{
		public key:string;
		public value:string;
		public constructor(key,value)
		{
			let s = this;
			s.key = key;
			s.value = value;
		}
	}
	class URLVariables{
		public variables:any;
		public constructor(source) {
			if (source === void 0) { source = null; }
			let s = this;
			s.variables = null;
			if (source !== null) {
				s.decode(source);
			}
		}
		public decode(source) {
			if (!this.variables) {
				this.variables = {};
			}
			source = source.split("+").join(" ");
			var tokens, re = /[?&]?([^=]+)=([^&]*)/g;
			while (tokens = re.exec(source)) {
				var key = decodeURIComponent(tokens[1]), val = decodeURIComponent(tokens[2]);
				//没有重复键值，直接赋值
				if ((key in this.variables) == false) {
					this.variables[key] = val;
					continue;
				}
				//有重复键值，如果已经存在数组，直接push到数组，否则创建一个新数组
				var value = this.variables[key];
				if (value instanceof Array) {
					value.push(val);
				}
				else {
					this.variables[key] = [value, val];
				}
			}
		}
		public toString() {
			if (!this.variables) {
				return "";
			}
			var variables = this.variables;
			var stringArray = [];
			for (var key in variables) {
				stringArray.push(this.encodeValue(key, variables[key]));
			}
			return stringArray.join("&");
		}
		public encodeValue(key, value) {
			if (value instanceof Array) {
				return this.encodeArray(key, value);
			}
			else {
				return encodeURIComponent(key) + "=" + encodeURIComponent(value);
			}
		}
		public encodeArray(key, value) {
			if (!key)
				return "";
			if (value.length == 0) {
				return encodeURIComponent(key) + "=";
			}
			return value.map(function (v) { return encodeURIComponent(key) + "=" + encodeURIComponent(v); }).join("&");
		}
	}
	

	class URLLoaderDataFormat{
		public static BINARY = "binary";
		public static TEXT = "text";
		public static VARIABLES = "variables";
		public static JSON = "json";
		
	}
	
